﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Hotel.Domain;
using Hotel.Util;
using System.Data.Common;

namespace HOTEL.Dao
{
    public class PhongDao:BaseDAO
    {
        public List<PHONG> GetAll()
        {
            return _db.PHONGs.ToList();
        }

        public List<PHONG> GetValable()
        {
            return _db.PHONGs.Where(p => p.TRANG_THAI.MaTrangThai == 1).ToList();
        }
        public List<VIEW_PHONG> GetListAvable()
        {
            var listphong = _db.PHONGs.Where(p => p.TRANG_THAI.MaTrangThai == 1).ToList();

            var result = new List<VIEW_PHONG>();
            foreach (var item in listphong)
            {
                var bgiaphong = _db.BANG_GIA_PHONGs.Where(p => p.MaLoaiPhong.Equals(item.MaLoaiPhong)
                    && p.MaHangPhong.Equals(item.MaHangPhong)).SingleOrDefault();
                if (bgiaphong != null)
                {
                    var vPhong = new VIEW_PHONG
                    {
                        Gia=bgiaphong.Gia,
                        HinhAnh=item.HinhAnh,
                        MaDay=item.MaDay,
                        MaHangPhong=item.MaHangPhong,
                        MaLoaiPhong=item.MaLoaiPhong,
                        MaPhong=item.MaPhong,
                        MaTang=item.MaTang,
                        MaTrangThai=item.MaTrangThai,
                        SoGiuong=item.LOAI_PHONG.SoGiuong,
                        TenHangPhong=item.HANG_PHONG.TenHangPhong,
                        TenLoaiPhong=item.LOAI_PHONG.TenLoaiPhong,
                        TenPhong=item.TenPhong,
                        TenTrangThai=item.TRANG_THAI.TenTrangThai,
                        TenTang=item.TANG_PHONG.TenTang,
                        TenDay = item.DAY_PHONG.TenDay
                    };
                    result.Add(vPhong);
                }
            }
            return result;
        }

        public List<PHONG> Search(int? maphong, String TenPhong, int? MaHangPhong, int? MaLoaiPhong, int? MaDayPhong, int? MaTang,int? trangthai)
        {
            var result = _db.PHONGs.AsQueryable();
            if (maphong.HasValue) result = result.Where(p => p.MaPhong.Equals(maphong.Value)).AsQueryable();
            if (!String.IsNullOrEmpty(TenPhong)) result = result.Where(p => p.TenPhong.Contains(TenPhong)).AsQueryable();
            if (MaHangPhong.HasValue) result = result.Where(p => p.MaHangPhong.Equals(MaHangPhong.Value)).AsQueryable();
            if (MaDayPhong.HasValue) result = result.Where(p => p.MaDay.Equals(MaDayPhong.Value)).AsQueryable();
            if (MaLoaiPhong.HasValue) result = result.Where(p => p.MaLoaiPhong.Equals(MaLoaiPhong.Value)).AsQueryable();
            if (MaTang.HasValue) result = result.Where(p => p.MaTang.Equals(MaTang.Value)).AsQueryable();
            if (trangthai.HasValue) result = result.Where(p => p.MaTrangThai.Equals(trangthai.Value)).AsQueryable();
            return result.OrderBy(p => p.MaTrangThai).ThenBy(p => p.MaTang).ThenBy(p => p.MaLoaiPhong).ToList();
        }
        public List<TRANG_THAI> GetListStatus()
        {
            return _db.TRANG_THAIs.ToList();
        }

        public List<BANG_GIA_PHONG> GetGiaByHangPhong(int mahang)
        {
            return _db.BANG_GIA_PHONGs.Where(p => p.MaHangPhong.Equals(mahang)).OrderBy(p => p.LOAI_PHONG.TenLoaiPhong).ToList();
        }
        public List<PHONG> Search(DateTime? TuNgay, DateTime? DenNgay, int? SoNguoi, int? LoaiPhong, int? HangPhong, int? SoPhong, Decimal? GiaTien)
        {
            var listphong = _db.PHONGs.AsQueryable();
            if (LoaiPhong.HasValue) listphong = listphong.Where(p => p.MaLoaiPhong.Equals(LoaiPhong.Value)).AsQueryable();
            if (HangPhong.HasValue) listphong = listphong.Where(p => p.MaHangPhong.Equals(HangPhong.Value)).AsQueryable();
            List<PHONG> result = new List<PHONG>();
            foreach (var phong in listphong)
            {
                if (GiaTien.HasValue)
                {
                    var banggia = _db.BANG_GIA_PHONGs.Where(p => p.MaLoaiPhong.Equals(p.MaLoaiPhong) &&
                        p.MaHangPhong.Equals(p.MaHangPhong)).SingleOrDefault();
                    if (banggia.Gia.HasValue && banggia.Gia <= GiaTien.Value)
                    {
                        if (phong.MaTrangThai.Value.Equals(TRANGTHAIPHONG.TRONG.GetHashCode()))
                        {
                            result.Add(phong);

                        }
                        else if (phong.MaTrangThai.Value.Equals(TRANGTHAIPHONG.DANGSUDUNG.GetHashCode()))
                        {
                            // thì xet cái ngày trả phòng  nhỏ hơn ngày đến
                            if (DenNgay.HasValue)
                            {
                                if (phong.NgayTra.HasValue && phong.NgayTra.Value <= DenNgay.Value)
                                {
                                    result.Add(phong);
                                }
                            }
                        }
                    }
                }
                else
                {
                    if (phong.MaTrangThai.Value.Equals(TRANGTHAIPHONG.TRONG.GetHashCode()))
                    {
                        result.Add(phong);

                    }
                    else if (phong.MaTrangThai.Value.Equals(TRANGTHAIPHONG.DANGSUDUNG.GetHashCode()))
                    {
                        // thì xet cái ngày trả phòng  nhỏ hơn ngày đến
                        if (DenNgay.HasValue)
                        {
                            if (phong.NgayTra.HasValue && phong.NgayTra.Value <= DenNgay.Value)
                            {
                                result.Add(phong);
                            }
                        }
                    }
                }
            }
            if (SoNguoi.HasValue)
            {
                var sumsonguoi = result.Sum(p => p.LOAI_PHONG.SoGiuong);
                if (sumsonguoi.HasValue && sumsonguoi >= SoNguoi.Value)
                {
                    if (SoPhong.HasValue)
                    {
                        if (SoPhong.Value <= result.Count)
                        {
                            return result;
                        }
                        else
                            return null;
                    }
                    else
                        return result;
                }
                else return null;
            }
            else
            {
                if (SoPhong.HasValue)
                {
                    if (SoPhong.Value <= result.Count)
                    {
                        return result;
                    }
                    else
                        return null;
                }
                else
                    return result;
            }
        }
        public List<HANG_PHONG> GetHangPhongAvalilable(DateTime? TuNgay, DateTime? DenNgay, int? SoNguoi, int? LoaiPhong, int? HangPhong, int? SoPhong, Decimal? GiaTien)
        {
            var listphong = Search(TuNgay, DenNgay, SoNguoi, LoaiPhong, HangPhong, SoPhong, GiaTien);
            if (listphong == null)
                return null;
            return (from p in listphong
                   select p.HANG_PHONG).Distinct().ToList();
        }
        public List<LOAI_PHONG> GetLoaiPhongAvalilable(int mahangphong, DateTime? TuNgay, DateTime? DenNgay, int? SoNguoi, int? LoaiPhong, int? HangPhong, int? SoPhong, Decimal? GiaTien)
        {
            var listphong = Search(TuNgay, DenNgay, SoNguoi, LoaiPhong, HangPhong, SoPhong, GiaTien);
            return (from p in listphong
                    where p.MaHangPhong.Equals(mahangphong)
                    select p.LOAI_PHONG).Distinct().ToList();
        }
        public BANG_GIA_PHONG GetBangGiaPhong(int mahang, int maloai)
        {
            return _db.BANG_GIA_PHONGs.SingleOrDefault(p => p.MaHangPhong.Equals(mahang) && p.MaLoaiPhong.Equals(maloai));
        }
        public int CountPhongAvalilable(int mahang, int maloai)
        {
            return _db.PHONGs.Where(p => p.MaHangPhong.Equals(mahang)
                && p.MaLoaiPhong.Equals(maloai)
                && p.MaTrangThai.Equals(TRANGTHAIPHONG.TRONG.GetHashCode())).Count();
        }

        public int CheckEnoughtOrder(List<MyRoom> objlistPhong,MyCart mycart )
        {
            for (int i = 0; i < objlistPhong.Count; i++)
            {
                var list = _db.PHONGs.Where(p => p.MaLoaiPhong.Equals(objlistPhong[i].MaLoaiPhong.Value)
                    && p.MaHangPhong.Equals(objlistPhong[i].MaHangPhong.Value)
                    && (p.MaTrangThai.HasValue && p.MaTrangThai.Value.Equals(TRANGTHAIPHONG.TRONG.GetHashCode())
                    || (p.NgayTra.HasValue && p.NgayTra.Value<=mycart.TuNgay))).ToList();
                if (list.Count < objlistPhong[i].SoLuong)
                {
                    return 0;   
                }
            }
            return 1;
        }
        public int Order(List<MyRoom> objlistPhong, MyCart mycart)
        {
            DbTransaction trans = null;
            _db.Connection.Open();
            trans = _db.Connection.BeginTransaction();
            _db.Transaction = trans;
            var phidatphong = new PHIEU_DAT_PHONG
            {
                MaPhieuDat=DateTime.Now.ToString("yyMMddhhss"),
                HoTen = mycart.TenDonHang,
                CMND = mycart.CMND,
                NgayDat = DateTime.Now,
                NgayDen = mycart.TuNgay,
                NgayDi = mycart.DenNgay,
                SoLuong = objlistPhong.Sum(p => p.SoLuong).Value,
                TongTien = mycart.TongTien,
                TraTruoc = mycart.TongTien,
                MaTinhTrang=1,
                IsThanhToan=false
            };
            _db.PHIEU_DAT_PHONGs.InsertOnSubmit(phidatphong);
            _db.SubmitChanges();
            var listchietietphieudat=new List<CT_PHIEU_DAT_PHONG>();
            for (int i = 0; i < objlistPhong.Count; i++)
            {
                var list = _db.PHONGs.Where(p => p.MaLoaiPhong.Equals(objlistPhong[i].MaLoaiPhong.Value)
                    && p.MaHangPhong.Equals(objlistPhong[i].MaHangPhong.Value)
                    && (p.MaTrangThai.HasValue && p.MaTrangThai.Value.Equals(TRANGTHAIPHONG.TRONG.GetHashCode())
                    || (p.NgayTra.HasValue && p.NgayTra.Value <= mycart.TuNgay))).OrderBy(p=>p.MaTang).ThenBy(p=>p.MaPhong).ToList();
                if (list.Count < objlistPhong[i].SoLuong)
                {
                    trans.Rollback();
                    _db.Connection.Close();
                    return 0;
                }
                else
                {
                    int countp = 0;
                    foreach(var p in list)
                    {
                        // nếu mã phòng còn trống thì mởi đổi trạng thái của phòng
                        if (p.MaTrangThai.Value.Equals(TRANGTHAIPHONG.TRONG.GetHashCode()))
                        {
                            p.MaTrangThai = TRANGTHAIPHONG.DANGDAT.GetHashCode();
                            p.NgayDat = mycart.TuNgay;
                            p.NgayTra = mycart.DenNgay;
                            _db.SubmitChanges();
                        }
                        var chitietphieudat = new CT_PHIEU_DAT_PHONG
                        {
                            MaPhong=p.MaPhong,
                            MaPhieuDat=phidatphong.MaPhieuDat,
                            DonGia = objlistPhong[i].Gia,
                            MaTinhTrang=TRANGTHAI_CHITIET_PHIEUDATPHONG.DANGCHO.GetHashCode(),
                            PhanTramTienHuy=0
                        };
                        listchietietphieudat.Add(chitietphieudat);
                        countp++;
                        if (countp == objlistPhong[i].SoLuong)// đếm đủ số lượng phòng của loại phòng này thì thôi
                        {
                            break;
                        }
                    }
                }
            }
            _db.CT_PHIEU_DAT_PHONGs.InsertAllOnSubmit(listchietietphieudat);
            _db.SubmitChanges();
            trans.Commit();
            _db.Connection.Close();
            return 1;
        }
        public PHONG Get(int maphong)
        {
            return _db.PHONGs.Where(p => p.MaPhong.Equals(maphong)).SingleOrDefault();
        }

        public Message Insert(PHONG objUi)
        {
            Message msg;
            try
            {

                _db.Connection.Open();

                _db.PHONGs.InsertOnSubmit(objUi);
                _db.SubmitChanges();

                // commit

                // success message
                msg = new Message(MessageConstants.I_CREATE_SUCCEED, MessageType.Info, "loại phòng ");
            }
            catch (Exception ex)
            {
                // rollback transaction

                msg = ExceptionHandler.HandleInsertException(ex, "loại phòng ", objUi.TenPhong);
            }
            return msg;
        }

        public Message Update(PHONG objUi)
        {
            Message msg;
            try
            {
                // get current object in database
                var objDb = Get(objUi.MaPhong);

                if (objDb != null)
                {
                    //TODO: update all fields
                    objDb.TenPhong = objUi.TenPhong;
                    
                    _db.SubmitChanges();

                    // success message
                    msg = new Message(MessageConstants.I_UPDATE_SUCCEED, MessageType.Info, " phòng ");
                }
                else
                {
                    // error message
                    msg = new Message(MessageConstants.E_OBJECT_IN_USED, MessageType.Error, " phòng ", objUi.TenPhong);
                }
            }
            catch (Exception ex)
            {
                msg = ExceptionHandler.HandleUpdateException(ex, "phòng ", objUi.TenPhong);
            }
            return msg;
        }

        public bool IsInUse(string ma)
        {
            return true;// _db.SANPHAMs.Where(p => p.LOAI_PHONG.Equals(ma)).Count() > 0;
        }

        public Message Delete(PHONG objUi)
        {
            Message msg;

            try
            {
                // Get current Item in db
                var objDb = Get(objUi.MaPhong);

                if (objDb == null)
                {
                    // error message
                    msg = new Message(MessageConstants.E_OBJECT_NOT_EXISTS, MessageType.Error, "phòng  ", objUi.TenPhong);
                    return msg;
                }


                // Set delete info
                _db.PHONGs.DeleteOnSubmit(objDb);
                // Submit changes to db
                _db.SubmitChanges();

                // success message
                msg = new Message(MessageConstants.I_DELETE_SUCCEED, MessageType.Info, "phòng  ");
            }
            catch (Exception ex)
            {
                msg = ExceptionHandler.HandleDeleteException(ex, "phòng  ");
            }

            return msg;
        }

        public Message ThemDichVu(SU_DUNG_DICH_VU objUi)
        {
            Message msg;
            try
            {
                _db.Connection.Open();
                _db.SU_DUNG_DICH_VUs.InsertOnSubmit(objUi);
                _db.SubmitChanges();
                // commit
                // success message
                msg = new Message(MessageConstants.I_CREATE_SUCCEED, MessageType.Info, "dịch vụ");
            }
            catch (Exception ex)
            {
                // rollback transaction

                msg = ExceptionHandler.HandleInsertException(ex, "dịch vụ", objUi.PHIEU_THUE_PHONG.TenKhachHang);
            }
            return msg;
        }

        public void CapNhatTrangThaiHuy(int id, int tt)
        {
            var objPhong = Get(id);
            if (objPhong != null)
            {
                //TODO: update all fields
                objPhong.MaTrangThai = tt;
                objPhong.NgayDat = null;
                objPhong.NgayTra = null;
                _db.SubmitChanges();
            }
        }
        public void CapNhatTrangNhan(int id, int tt)
        {
            var objPhong = Get(id);
            if (objPhong != null)
            {
                //TODO: update all fields
                objPhong.MaTrangThai = tt;
                _db.SubmitChanges();
            }
        }

    }
}
